#pragma once

/**
 * 用户使用muduo编写程序服务器
 */
#include "EventLoop.h"
#include "Acceptor.h"
#include "InetAddress.h"
#include "noncopyable.h"
#include "EventLoopThreadPool.h"
#include "TcpConnection.h"
#include "Buffer.h"
#include"Callbacks.h"
// #include "TcpConnection.hpp"
// #include "Buffer.hpp"
#include <functional>
#include <string>
#include <memory>
#include <atomic>
#include <unordered_map>
class TcpServer : noncopyable
{
public:
    using ThreadInitCallback = std::function<void(EventLoop *)>;
    enum Option
    {
        kNoReusePort,
        kReusePort,
    };

    TcpServer(EventLoop *loop,
              const InetAddress &listenAddr,
              const std::string& nameArg,
              Option option = kNoReusePort);
    ~TcpServer();

    // 设置底层subloop的个数
    void setThreadNum(int numThreads);

    void setThreadInitcallback(const ThreadInitCallback &cb) {  threadInitCallback_ = cb;}
    
    void setConnectionCallback(const ConnectionCallback & cb){connectionCallback_ = cb;}
    void setMessageCallback(const MessageCallback & cb){messageCallback_ = cb;}
    void setWriteCompleteCallback(const WriteCompleteCallback& cb) {writeCompleteCallback_ = cb;}
    // 开启服务器监听
    void start();
private:
    void newConnection(int sockfd,const InetAddress& peerAddr);
    void removeConnection(const TcpConnectionPtr & conn);
    void removeConnectionInLoop(const TcpConnectionPtr& conn);
    using ConnectionMap = std::unordered_map<std::string, TcpConnectionPtr>;

private:
    EventLoop *loop_; // baseLoop 用户定义的loop
    const std::string ipPort_;
    const std::string name_;
    // mainloop 中的acceptor，监听新连接事件
    std::unique_ptr<Acceptor> acceptor_; // Accept 里面有Channel，所以这里相当于unique_ptr<Accepto>
    // 用户设置底层线程池中线程的数量。
    std::shared_ptr<EventLoopThreadPool> threadPool_; // one loop per thread

    ConnectionCallback connectionCallback_;       // 有新连接时的回调
    MessageCallback messageCallback_;             // 有读写消息时的回调
    WriteCompleteCallback writeCompleteCallback_; // 消息发送完成以后的回调

    ThreadInitCallback threadInitCallback_; // loop线程初始化的回调
    std::atomic_int started_;

    int nextConnId_;
    ConnectionMap connections_; // 保存所有的链接
};